Imports System.Windows.Forms
Imports System.Text.RegularExpressions
'Imports System.Windows.Forms
Module modParse
    Private Delegate Sub NoParamsDelegate()
    Private offlineNode As Int32 = frmMain.tvContacts.Nodes.IndexOf(New TreeNode("Offline"))
    Private onlineNode As Int32 = frmMain.tvContacts.Nodes.IndexOf(New TreeNode("Online"))
    Private Delegate Sub twoStrParamDlg(ByVal user As String, ByVal whichNode As String)
    
    Enum OnOff
        Offline = 0
        Online = 1
    End Enum
    Public Sub parseFriends(ByVal sData As String)
        Dim reWhatsNext As Regex = New Regex("[a-zA-Z0-9_. :]+[GROUPS:{|OFFLINE_FROM_]")
        sData = reWhatsNext.Match(sData).ToString
        Dim Uname As String, uID As String, args(1) As Object
        Dim dlg As New twoStrParamDlg(AddressOf addNodeToContactList)
        Dim re As Regex = New Regex(" ?[a-zA-Z0-9_.]+:[0|1]")
        Dim matchArr As MatchCollection = re.Matches(sData)
        For Each reMatch As Match In matchArr
            Dim match As String = reMatch.ToString
            Uname = match.Substring(IIf(match.Substring(0, 1) = " ", 1, 0), _
            match.IndexOf(":") - IIf(match.Substring(0, 1) = " ", 1, 0))
            Select Case CType(match.Substring(match.Length - 1), Int32)
                Case OnOff.Offline
                    args(0) = Uname
                    args(1) = "Offline"
                Case OnOff.Online
                    args(0) = Uname
                    args(1) = "Online"
            End Select
            frmMain.Invoke(dlg, args)
        Next
        'Dim x As Double = 0
        'Do Until 0 >= Len(sData) Or sData.Substring(0, 13) = "OFFLINE_FROM_"
        '    Uname = sData.Substring(0, sData.IndexOf(":"))
        '    'x += Uname.Length
        '    Select Case sData.Substring(sData.IndexOf(":") + 1, 1)
        '        Case "1"
        '            frmMain.tvContacts.Nodes(onlineNode).Nodes.Add(Uname)
        '        Case "0"
        '            frmMain.tvContacts.Nodes(offlineNode).Nodes.Add(Uname)
        '    End Select
        '    'x += 3
        '    sData = sData.Substring(sData.IndexOf(" ") + 1)
        'Loop
        'parseFriends = Data
    End Sub
    Public Function parseOfflines(ByVal data As String) As String
        'An Offline String is Formatted as follows:
        'OFFLINEFROM_username@00/00/0000 00:00:00(A|P)M:14{This is a test}
        'Dim re As Regex = New Regex( _
        '  "OFFLINEFROM_[a-zA-Z0-9_.]+@\d{4}/[0-2]\d/[0-3]\d [0-2]\d:" + _
        '  "[0-5]\d:[0-5]\d\(A|P)M:\d+\{[\s\S]+\}") 'I think that wraps it up
        'Dim OfflineMatches As MatchCollection = re.Matches(data)
        'For Each mtcMatch As Match In OfflineMatches
        'Dim reUN As Regex = New Regex("_[a-zA-Z0-9_.]+@")
        'Dim reTime As Regex = New Regex( _
        '+"@\d{4}/[0-2]\d/[0-3]\d [0-2]\d:[0-5]\d:[0-5]\d\(A|P)M:")
        'Dim reMsgLen As Regex = New Regex(":\d+\{")
        'Dim reMsg As Regex = New Regex("\{[\s\S]\}")
        'Dim sUsername As String = reUN.Match(mtcMatch.ToString).ToString
        'sUsername = sUsername.Substring(1, sUsername.Length - 1)
        'Dim sTime As String = reTime.Match(mtcMatch.ToString).ToString
        'sTime = sTime.Substring(1, sTime.Length - 1)
        'Dim iMsgLen As Int32 = _
        '  CType(reMsgLen.Match(mtcMatch.ToString).ToString.Substring( _
        '  1, reMsgLen.Match(mtcMatch.ToString).ToString.Length), Int32)
        'Dim sMsg As String = reMsg.Match(mtcMatch.ToString).ToString
        'sMsg = sMsg.Substring(1, sMsg.Length - 1)
        'If sMsg.Length = iMsgLen Then
        'If ofln(0) Is Nothing Then
        '            ofln(0)=new clsOfflines(
        'End If
        'End If

        'Next
        If frmOfflines Is Nothing Then frmOfflines = New FormOfflineView
        Do Until data = vbNullString Or data.Substring(0, 8) = "GROUPS:{"
            If ofln.GetUpperBound(0) = 0 And ofln(0).Message = vbNullString Then
                data = ofln(0).formatMSG(data)
                frmOfflines.lstOfflineHeader.Items.Add(ofln(0).MessageHeader)
            Else
                ReDim Preserve ofln(UBound(ofln) + 1)
                ofln(UBound(ofln)) = New clsOfflines
                data = ofln(UBound(ofln)).formatMSG(data)
                frmOfflines.lstOfflineHeader.Items.Add(ofln(UBound(ofln)).MessageHeader)
            End If
        Loop
        'parseOfflines = data.Substring(data.IndexOf("OFFLINEFROM_"))
        parseOfflines = data
        Dim dlg As New NoParamsDelegate(AddressOf frmOfflines.Show)
        frmMain.Invoke(dlg)
        frmOfflines.lstOfflineHeader.SelectedIndex = 0
    End Function
    '!' These 2 functions are now depriciated since we have ArrayLists working in their place
    'Public Sub parseMessage(ByVal data As String)
    '    Dim FromUser As String = vbNullString
    '    For x As Integer = 0 To Len(data)
    '        If Mid(data, x + 9, 1) = ":" Then Exit For
    '        FromUser += Mid(data, x + 9, 1)
    '    Next
    '    Dim MsgFromUser As String = Mid(data, 12 + Len(FromUser), Len(data) - 10 - Len(FromUser))
    '    Dim Index As Integer = FindOpenMessageWindow(FromUser)
    '    With frmMessageWindow(Index)
    '        If Len(.txtLog.Text) <> 0 Then .txtLog.Text = .txtLog.Text + vbNewLine
    '        .txtLog.Text = .txtLog.Text + FromUser + ": " + MsgFromUser
    '        .Text = "STIMPy! - Chatting with " + FromUser
    '        .Show()
    '        .txtLog.SelectionStart = Len(.txtLog.Text)
    '    End With
    'End Sub
    'Public Function FindOpenMessageWindow(ByVal user As String) As Integer
    '    Dim x As Integer
    '    For x = 0 To UBound(frmMessageWindow)
    '        If frmMessageWindow(x).Text.Length > 24 Then
    '           If user = Right(frmMessageWindow(x).Text, _
    '            frmMessageWindow(x).Text.Length - 24) Then
    '                FindOpenMessageWindow = x
    '                Exit Function
    '             End If
    '        ElseIf frmMessageWindow(x).Loaded = False Then
    '            frmMessageWindow(x) = New frmMessaging
    '           FindOpenMessageWindow = x
    '            Exit Function
    '        End If
    '    Next
    '   ReDim Preserve frmMessageWindow(UBound(frmMessageWindow) + 1)
    '    frmMessageWindow(UBound(frmMessageWindow)) = New frmMessaging
    '    FindOpenMessageWindow = UBound(frmMessageWindow)
    'End Function

    'This subroutine is called when a contact changes status (ie. Online/Offline)
    Public Sub parseStatus(ByRef sData As String)
        sData = sData.Trim
        Dim re As Regex = New Regex("(ONLINE|OFFLINE):")
        Dim dlg As New twoStrParamDlg(AddressOf moveUserToNode)
        Dim args(1) As Object
        Select Case re.Match(sData).ToString
            Case "ONLINE:"
                frmMain.playSound(App.SoundPath + "ContactOn")
                args(0) = sData.Substring(sData.IndexOf(":") + 1)
                args(1) = "Online"
            Case "OFFLINE:"
                frmMain.playSound(App.SoundPath + "ContactOff")
                args(0) = sData.Substring(sData.IndexOf(":") + 1)
                args(1) = "Offline"
        End Select
        frmMain.Invoke(dlg, args)
        'If Left(sData, 7) = "ONLINE:" Then
        'If frmMain.tvContacts.Nodes(offlineNode).Nodes.Contains(New TreeNode(sData.Substring(7))) Then _
        'frmMain.tvContacts.Nodes(offlineNode).Nodes.Remove(New TreeNode(sData.Substring(7)))
        'frmMain.tvContacts.Nodes(onlineNode).Nodes.Add(sData.Substring(7))
        'ElseIf Left(sData, 8) = "OFFLINE:" Then
        'If frmMain.tvContacts.Nodes(onlineNode).Nodes.Contains(New TreeNode(sData.Substring(7))) Then _
        'frmMain.tvContacts.Nodes(onlineNode).Nodes.Remove(New TreeNode(sData.Substring(7)))
        'frmMain.tvContacts.Nodes(offlineNode).Nodes.Add(sData.Substring(8))
        'End If
    End Sub
    Public Sub parseGroups(ByVal sData As String)
        sData = sData.Substring(8)
        Do Until sData = "}"
            If sData.IndexOf(",") > 0 Then
                frmMain.lstGroupList.Items.Add(sData.Substring(0, sData.IndexOf(",")))
                sData = sData.Substring(sData.IndexOf(",") + 1)
            Else
                frmMain.lstGroupList.Items.Add(sData.Substring(0, sData.IndexOf("}")))
                sData = sData.Substring(sData.IndexOf("}"))
            End If
        Loop
    End Sub
    Public Sub parseFriendResult(ByVal sdata As String)
        frmFriendSearch.lstFriendResults.Items.Clear()
        If sdata.Length = 0 Then frmFriendSearch.lstFriendResults.Items.Add("No Results")
        Do Until sdata.Length = 0
            If Not sdata.IndexOf(":") = -1 Then
                frmFriendSearch.lstFriendResults.Items.Add(sdata.Substring(0, _
                  sdata.IndexOf(":")))
                sdata = sdata.Substring(sdata.IndexOf(":") + 1)
            Else
                frmFriendSearch.lstFriendResults.Items.Add(sdata.Substring(0))
                sdata = ""
            End If
        Loop
    End Sub
    Public Sub parseFriendConfirmation(ByVal sdata As String)
        'This will be used in a future release to get user confirmation for friends
    End Sub
    Private Sub addNodeToContactList(ByVal user As String, ByVal whichNode As String)
        'SyncLock frmMain.tvContacts
        'MsgBox(user)
        If Threading.Thread.CurrentThread.Name Is Nothing Then _
          Threading.Thread.CurrentThread.Name = "AddNodeToContacts"
        Dim userNode As TreeNode = New TreeNode(user)
        Dim NodeID As Int32 = frmMain.htTVNodes.Item(whichNode)
        frmMain.tvContacts.Nodes(NodeID).Nodes.Add(user)
        'frmMain.tvContacts.Update()
        'End SyncLock
    End Sub
    Private Sub moveUserToNode(ByVal user As String, ByVal whichNode As String)
        If Threading.Thread.CurrentThread.Name Is Nothing Then _
          Threading.Thread.CurrentThread.Name = "AddNodeToContact"
        Dim sMatch As String
        For Each node As TreeNode In frmMain.tvContacts.Nodes
            If node.Nodes.Count > 0 Then _
              sMatch = TraverseNodes("\" + node.Index.ToString, user)
            If Not sMatch Is Nothing Then Exit For
        Next
        If Not sMatch Is Nothing Then
            Dim re As Regex = New Regex("[0-9]+")
            Dim ReMatches As MatchCollection = re.Matches(sMatch)
            Dim nodNode As TreeNode, iNodeToDelete As Int32
            For Each mtcIndex As Match In ReMatches
                Dim iIndex As Int32 = CType(mtcIndex.ToString, Int32)
                'If this is the first node, then we must use the tree to reference nodNode
                If CType(ReMatches.Item(0).ToString, Int32) = iIndex Then
                    nodNode = frmMain.tvContacts.Nodes(iIndex)
                ElseIf iIndex = CType(ReMatches.Item(ReMatches.Count _
                  - 1).ToString, Int32) Then
                    iNodeToDelete = iIndex
                Else 'Otherwise, just use the node for the reference
                    nodNode = nodNode.Nodes(iIndex)
                End If
            Next
            nodNode.Nodes.RemoveAt(iNodeToDelete)
        End If
        Dim userNode As TreeNode = New TreeNode(user)
        Dim NodeID As Int32 = frmMain.htTVNodes.Item(whichNode)
        frmMain.tvContacts.Nodes(NodeID).Nodes.Add(user)
        frmMain.tvContacts.Update()
    End Sub
    Private Function TraverseNodes(ByVal node As String, ByVal searchStr As String, _
       Optional ByVal searchParentNodes As Boolean = False) As String
        'We will use this to get to the current node to search
        'node will look like \1\2\3\4\5
        'This means in the first node, we will be looking at the second subnode
        'When we look at the subnode, we will be looking at the third subnode and so on
        'This will allow the user to have groups under groups for better organization,
        'and will allow us to be able to easily make our way through the tree
        Dim re As Regex = New Regex("[0-9]+")
        'Now we get the exact location where we need to be searching
        Dim ReMatches As MatchCollection = re.Matches(node)
        'Declare our Node
        Dim nodNode As TreeNode
        'Get to current node
        For Each mtcIndex As Match In ReMatches
            Dim iIndex As Int32 = CType(mtcIndex.ToString, Int32)
            'If this is the first node, then we must use the tree to reference nodNode
            If CType(ReMatches.Item(0).ToString, Int32) = iIndex Then
                nodNode = frmMain.tvContacts.Nodes(iIndex)
            Else 'Otherwise, just use the node for the reference
                nodNode = nodNode.Nodes(iIndex)
            End If
        Next
        'Now we should be at the current position
        'Keeping mind that if we are here, then we haven't found a match yet
        'Declare MatchIndex as the index for the match and matchString for the path
        Dim iMatch As Int32, sMatch As String, sPath As String
        'If there are subnodes of a node, we will be passing the sMatch into it
        'with the node index at the end
        'If a match is found, we will append the node index to this string and return
        sPath += node + "\"
        '--When we get to searching parent nodes, we will have to look at every node
        '--because a parent node may be empty. if that is the case, then
        '--Node.Nodes.Count can be 0
        'Traverse through the nodes in the current node
        For Each subNode As TreeNode In nodNode.Nodes
            'If this node contains subnodes
            If Not subNode.Nodes.Count = 0 Then 'IIf(Not searchParentNodes, True, Not subNode.Nodes.Count = 0) Then
                'Search the subnode
                sMatch = TraverseNodes(sPath + subNode.Index.ToString, searchStr)
                'If there is a match found, then exit this for loop
                If Not sMatch Is Nothing Then Exit For
            Else 'If node has no subnodes
                If subNode.Text = searchStr Then
                    sMatch = sPath + subNode.Index.ToString
                    Exit For
                End If
            End If
        Next
        'Now we either have a match, or we don't
        'If nodMatch is nothing, that means no match was found
        'if nodMatch has been populated, then we have a match
        'Return what we found, whether we found what we were looking for or not
        TraverseNodes = sMatch
        ' JMS 8-14-06 Replace blow with line above
        'If Not sMatch Is Nothing Then
        ''No match = return nothing
        'TraverseNodes = Nothing
        'Else
        '    'Match found = return matching node
        '    TraverseNodes = sMatch
        'End If
    End Function
End Module
